/**
 * 
 */
package freedom.platform.security;

import java.util.Collection;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.annotation.Jsr250SecurityConfig;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

/**
 * @author charlie
 *
 */
public class AccessDecisionVoter implements org.springframework.security.access.AccessDecisionVoter<Object> {

	/* (non-Javadoc)
	 * @see org.springframework.security.access.AccessDecisionVoter#supports(org.springframework.security.access.ConfigAttribute)
	 */
	@Override
	public boolean supports(ConfigAttribute attribute) {
		return attribute instanceof Jsr250SecurityConfig;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.access.AccessDecisionVoter#supports(java.lang.Class)
	 */
	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.access.AccessDecisionVoter#vote(org.springframework.security.core.Authentication, java.lang.Object, java.util.Collection)
	 */
	@Override
	public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
		boolean attributeFound = false;

		for (ConfigAttribute attribute : attributes) {
			if (Jsr250SecurityConfig.PERMIT_ALL_ATTRIBUTE.equals(attribute)) {
				return ACCESS_GRANTED;
			}

			if (Jsr250SecurityConfig.DENY_ALL_ATTRIBUTE.equals(attribute)) {
				return ACCESS_DENIED;
			}

			if (supports(attribute)) {
				attributeFound = true;
				// Attempt to find a matching granted authority
				for (GrantedAuthority authority : authentication.getAuthorities()) {
					if (attribute.getAttribute().equals(authority.getAuthority())) {
						return ACCESS_GRANTED;
					}
				}
			}
		}

		return attributeFound ? ACCESS_DENIED : ACCESS_ABSTAIN;
	}

}
